package com.uxsino.commons.db.redis.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.alibaba.fastjson.JSON;
import com.uxsino.commons.db.redis.IReadRedisRepostory;
import com.uxsino.commons.db.redis.IWriteRedisRepostory;

/**
 * 基于 StringRedisTemplate 和 fastjson 实现redis 操作
 * 
 *
 * @param <T>
 */
public abstract class AbstractRedisRepostory<T> implements IReadRedisRepostory<T>, IWriteRedisRepostory<T> {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HashOperations<String, String, String> hashOperations;

    @Override
    public void put(String key, T t) {
        put(key, t, -1);
    }

    @Override
    public void put(String key, T t, long expire) {
        hashOperations.put(getRedisKey(), key, JSON.toJSONString(t));
        if (expire != -1) {
            stringRedisTemplate.expire(getRedisKey(), expire, TimeUnit.SECONDS);
        }
    }

    @Override
    public void remove(String key) {
        hashOperations.delete(getRedisKey(), key);
    }

    @Override
    public void empty() {
        Set<String> set = hashOperations.keys(getRedisKey());
        set.stream().forEach(key -> hashOperations.delete(getRedisKey(), key));
    }

    @Override
    public T get(String key) {
        return JSON.parseObject((String) hashOperations.get(getRedisKey(), key), getSerializeClass());
    }

    protected abstract TypeReference<T> getSerializeClass();

    @Override
    public List<T> getAll() {
        List<T> datas = new ArrayList<>();
        List origins = hashOperations.values(getRedisKey());
        if(origins == null){
            return datas;
        }
        origins.parallelStream().forEach(itm->{
            datas.add(JSON.parseObject(JSON.toJSONString(itm), getSerializeClass()));
        });
        return datas;
    }

    @Override
    public Set<String> getKeys() {
        return hashOperations.keys(getRedisKey());
    }

    @Override
    public boolean isKeyExists(String key) {
        return hashOperations.hasKey(getRedisKey(), key);
    }

    @Override
    public long count() {
        return hashOperations.size(getRedisKey());
    }

}
